package tcpService

import (
	"context"
	"fmt"
	"github.com/fatih/color"
	"go_gateway/dao"
	reverseProxy "go_gateway/reverse_proyx"
	tcpMiddleware "go_gateway/service_tcp/middleware"
	tcpServer "go_gateway/service_tcp/server"
	"log"
)

var tcpServerList = []*tcpServer.TcpServer{}

type tcpHandler struct{}

func TcpServerRun() {
	// 1.获取TCP服务列表
	serviceList := dao.ServiceManagerHandler.GetTcpServiceList()
	// 2.为每一个tcp服务创建服务
	for _, serviceItem := range serviceList {
		tempItem := serviceItem
		// 2.1 开启单独携程处理服务
		go func(serviceDetail *dao.ServiceDetail) {
			// 2.1.1 获取服务负载均衡器
			addr := fmt.Sprintf(":%d", serviceDetail.TCPRule.Port)
			rb, err := dao.LoadBalancerManager.GetLoadBalancer(serviceDetail)
			if err != nil {
				log.Fatalf("[INFO] GetTcpLoadBalance %v err: %v\n", addr, err)
				return
			}
			// 2.1.2 获取tcp服务的router
			router := tcpMiddleware.NewTcpSliceRouter()
			// 2.1.3 设置中间件
			router.Group("/").Use(
				tcpMiddleware.TCPFlowCountMiddleware(),
				tcpMiddleware.TCPFlowLimitMiddleware(),
				tcpMiddleware.TCPWhiteListMiddleware(),
				tcpMiddleware.TCPBlackListMiddleware(),
			)

			// 2.1.4 获取tcp服务handler
			routerHandler := tcpMiddleware.NewTcpSliceRouterHandler(
				func(c *tcpMiddleware.TcpSliceRouterContext) tcpServer.TCPHandler {
					return reverseProxy.NewTcpLoadBalanceReverseProxy(c, rb)
				}, router)

			// 2.1.5 创建ctx
			baseCtx := context.WithValue(context.Background(), "service", serviceDetail)

			// 2.1.6 创建tcp服务
			tcpSer := &tcpServer.TcpServer{
				Addr:    addr,
				Handler: routerHandler,
				BaseCtx: baseCtx,
			}
			tcpServerList = append(tcpServerList, tcpSer)
			log.Printf("%s %s %s\n", color.GreenString("[INFO]"), color.BlueString("TCP_PROXY RUN"), addr)
			// 2.1.7 启动tcp服务
			err = tcpSer.ListenAndServe()
			if err != nil && err != tcpServer.ErrServerClosed {
				log.Fatalf("[INFO] tcp proxy run %v err:%v\n", addr, err)
			}
		}(tempItem)
	}
}

// TcpServerStop
// @Description: 停止tcp服务
func TcpServerStop() {
	for _, server := range tcpServerList {
		err := server.Close()
		if err != nil {
			fmt.Printf("tcp_proxy_stop %v err: %s\n", server.Addr, err)
			continue
		}
		log.Printf("%s %s \n", color.GreenString("[INFO]"), color.BlueString("TCP_PROXY STOP"))
	}
}
